/*

Stickman Adventure - a game created by Daco & his cousin

Copyright (C) 2011-2012  DacoTaco & Wouterke

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation version 2.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


*/
#include "Object.h"

//amount of frames in sheet from left 2 right
#define SHEET_FRAMES 4


// constructor Object with sound
Object::Object(const char* spritesheet,int xpos , int ypos, int h, int w ,char typeObj,const char* sound[],int soundlength)
{
	initObject(spritesheet ,xpos ,ypos ,h ,w ,typeObj );
	int i=0;
	if(sound !=NULL){
		while(i<soundlength && sound[i]!= NULL && sound[i]!= ""){
			Mix_Chunk * s= sound_collection.addData(sound[i]);
			if(s != NULL) {
				sounds.push_back(s);
				sound_names.push_back(sound[i]);
			}
			i++;

		}
	}
	


}
// constructor Object w/o sound
Object::Object(const char* spritesheet,int xpos , int ypos,int h,int w,char typeObj){
	initObject(spritesheet ,xpos ,ypos ,h ,w ,typeObj );
}

//initializer is used 2 help construct the object in the constructers
void Object::initObject(const char* spritesheet,int xpos , int ypos,int h,int w,char typeObj){
	if(spritesheet != NULL && spritesheet != "")
	{
		sheet_name=spritesheet;
		sheet = image_collection.addData(spritesheet);
	}
	else
	{
		sheet_name = "";
		sheet = NULL;
	}
	frame = 0;
	x = xpos;
	y = ypos;
	height = h;
	width = w;
	type = typeObj;
#ifdef OGL_MODE
	if(sheet != NULL)
	{
		GLenum texture_format;
		GLint  nOfColors;

		// Check that the image's width is a power of 2. we can ignore this but its a JUST IN CASE
        if ( (sheet->w & (sheet->w - 1)) != 0 ) {
            printf("warning: %s's width is not a power of 2\n",sheet_name.c_str());
        }
    
        // Also check if the height is a power of 2
        if ( (sheet->h & (sheet->h - 1)) != 0 ) {
            printf("warning: %s's height is not a power of 2\n",sheet_name.c_str());
        }

		//we will create a new RGBA surface that will have all content of the real sheet. however a RGBA format is required for openGL.
		//what we need to know is that the alpha(which causes transparency) is generated by SDL's SDL_MapRGBA & SDL_SetColorKey
		SDL_Surface* sheet_new;
		Uint32 rmask, gmask, bmask, amask;

		//well, since we are dealing with pointers here, endianness is a big deal.
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
		rmask = 0xff000000;
		gmask = 0x00ff0000;
		bmask = 0x0000ff00;
		amask = 0x000000ff;
#else
		rmask = 0x000000ff;
		gmask = 0x0000ff00;
		bmask = 0x00ff0000;
		amask = 0xff000000;
#endif

		//create the new surface...
		sheet_new = SDL_CreateRGBSurface(SDL_HWSURFACE, sheet->w, sheet->h, 32,
									   rmask, gmask, bmask, amask);
		if(sheet_new == NULL)
		{
			texture = 0;
			return;
		}
		SDL_BlitSurface(sheet,0,sheet_new,0);  

		//check the data of the surface
		nOfColors = sheet_new->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
                if (sheet_new->format->Rmask == 0x000000ff)
                        texture_format = GL_RGBA;
                else
                        texture_format = GL_BGRA;
        } else if (nOfColors == 3)     // no alpha channel
        {
                if (sheet_new->format->Rmask == 0x000000ff)
                        texture_format = GL_RGB;
                else
                        texture_format = GL_BGR;
        } else {
                printf("warning: the image is not truecolor..  this will probably break\n");
                // this error should not go unhandled
        }

        // Have OpenGL generate a texture object handle for us
        glGenTextures( 1, &texture );
    
        // Bind the texture object
        glBindTexture( GL_TEXTURE_2D, texture );
        
        // Set the texture's stretching properties
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

        // Edit the texture object's image data using the information SDL_Surface gives us
        glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, sheet_new->w, sheet_new->h, 0, 
						texture_format, GL_UNSIGNED_BYTE, sheet_new->pixels );

		SDL_FreeSurface(sheet_new);
	}
	else
		texture = 0;
#endif
	return;
}

Object::~Object()
{
	image_collection.deleteData(sheet_name);
	for(unsigned int i=0 ; i < sound_names.size() ; i++)sound_collection.deleteData(sheet_name);
#ifdef OGL_MODE
	if(texture != 0)
		glDeleteTextures(1, &texture);
#endif
	
}

void Object::handle_events(SDL_Event e)
{
	
}

char Object::Update(int collision,int y_ground, int x_wall)
{
	return 0;
}
int Object::GetVelocity()
{
	return 0;
}
int Object::getXPosition()
{
	return x;
}

int Object::getYPosition()
{
	return y;
}

int Object::getWidth(){
	return width;
}

int Object::getHeight(){
	return height;
}

char Object::getType(){
	return type;
	//return 0;
}
SDL_Surface * Object::getImage()
{
	return sheet;
}

SDL_Rect* Object::getImageClip()
{
	clip.x=frame*width;	
	clip.y=height;
	clip.w=width;
	clip.h=height;
	return &clip;

}
SDL_Rect* Object::GetColRect()
{
	ColRect.x = x;
	ColRect.y = y;
	ColRect.w = width;
	ColRect.h = height;
	return &ColRect;
}
void Object::CollisionAction(Object* o, int collision)
{
	return;
}

void Object::draw(SDL_Surface* destination,Object* screen){
	if(destination != NULL && screen != NULL )
	{
		if(sheet != NULL)
		{
#ifdef OGL_MODE
			apply_surface(x-screen->x,y-screen->y,sheet->h,sheet->w,&texture,getImageClip());
#else
			apply_surface(x-screen->x,y-screen->y,sheet,destination,getImageClip());
#endif
		}
		else
		{
			int colour = 0x0e9747;
			if(type != OBJECT_BACKGROUND)
				colour = 0xFFFFFF;
			SDL_Rect rect = *Object::GetColRect();
			rect.x = x - screen->x;
			rect.y = y - screen->y;
			apply_surface(&rect,destination,colour);
		}
	}
}